/**
 *-----------------------------------------------------------------------------
 * @file state_flow_sample.c
 * @brief 状态机模板，用于FSM状态机设计参考，基于经典的地铁闸机模型，划分为
 *        Lock 和 Unlock 两种状态，每种状态下接收 CARD(刷卡) 和 PASS(强行闯入)
 *        两种事件，依据此进行软件逻辑搭建。
 * @author Shibo Jiang
 * @version 0.1
 * @date 2020-10-06
 * @note [change history] 
 * 
 * @copyright GEELY AUTOMOBILE RESEARCH INSTITUTE CO.,LTD Copyright (c) 2020
 *-----------------------------------------------------------------------------
 */

#include <stdio.h>

typedef signed char int8;
typedef unsigned char uint8;
typedef short int16;
typedef unsigned short uint16;
typedef int int32;
typedef unsigned int uint32;
typedef float real32;
typedef double real64;

typedef uint8 Std_ReturnType;

#ifndef E_OK
#define E_OK   ((uint8)0U)
#endif

#ifndef E_NOT_OK
#define E_NOT_OK   (1U)
#endif

typedef enum _state_em
{
    LOCKED   = 0x00,    
    UNLOCKED = 0x01,
}state_em;

typedef enum _event_em
{
    NO_EVENT = 0x00,    
    CARD     = 0x01,
    PASS     = 0x02,
}event_em;

typedef struct _transition_t
{
    state_em current_state;
    event_em event;
    state_em new_state;
    void (*entry_func)();
    void (*during_func)();
    void (*exit_func)(); 
}transition_t;

/* funciton declation -------------------------------------------------------*/
static void state_emtpy_func(void);
static void unlock_func(void);
static void lock_func(void);
Std_ReturnType stateflow_example(state_em current_st, event_em events);

transition_t transitions[] = 
{
    { LOCKED ,CARD ,UNLOCKED, &unlock_func,&unlock_func,&state_emtpy_func},
    { UNLOCKED ,PASS,LOCKED, &lock_func, &lock_func, &state_emtpy_func}
};

/**
 *-----------------------------------------------------------------------------
 * @brief main function
 * 
 *-----------------------------------------------------------------------------
 */
// uint8 main(void)
// {   
//     Std_ReturnType func1;
//     func1 = stateflow_example(LOCKED, CARD);
//     return func1;
// }

/**
 *-----------------------------------------------------------------------------
 * @brief stateflow example function
 * 
 * @param current_st 当前状态
 * @param events 发生事件
 * @return Std_ReturnType 返回函数执行状态是否有问题
 *-----------------------------------------------------------------------------
 */
Std_ReturnType stateflow_example(state_em current_st, event_em events)
{
    uint8 translate_num = sizeof(transitions)/sizeof(transitions[0]);
    void (*during_func)() = NULL;
    uint8 state_find_flg = 0u;

    for (int i = 0;i < translate_num;i++)
    {
        if (current_st == transitions[i].current_state)
        {  
            /* Log during function */
            during_func = &(transitions[i].during_func);
            /* Translate state judge*/
            if (events == transitions[i].event)
            {
                transitions[i].exit_func();
                transitions[i].entry_func();
                break;
            }
            state_find_flg = 1u;
        }
        /* Use positive flank to stop loop */
        else if (state_find_flg)
        {
            state_find_flg = 0u;
            break;
        }
    }
    /* Run during funciton */
    during_func();
    return E_OK;
}



/**
 *-----------------------------------------------------------------------------
 * @brief Empty function ,for state flow used
 * 
 *-----------------------------------------------------------------------------
 */
static void state_emtpy_func(void)
{
    /* Do Nothing*/
    printf("Run empty function");
}

/**
 *-----------------------------------------------------------------------------
 * @brief unlock function
 * 
 *-----------------------------------------------------------------------------
 */
static void unlock_func(void)
{
    /* Do Nothing*/
    printf("Run unlock funciton");
}

/**
 *-----------------------------------------------------------------------------
 * @brief lock function
 * 
 *-----------------------------------------------------------------------------
 */
static void lock_func(void)
{
    /* Do Nothing*/
    printf("Run lock fucntion");
}